package ldh.text;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
import ldh.text.service.FinderService;
import ldh.text.util.ThreadPoolUtil;
import ldh.text.vo.FindPosition;
import org.fxmisc.flowless.Cell;
import org.fxmisc.flowless.VirtualFlow;
import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.Selection;
import org.fxmisc.richtext.SelectionImpl;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;

public class VirtualFlowDemo extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        ObservableList<FindPosition> observableList = FXCollections.observableArrayList();
//        VirtualFlow<FindPosition, ?> virtualFlow = VirtualFlow.createVertical(observableList, t-> Cell.wrapNode(buildCell(t)));
        VirtualFlow<FindPosition, ?> virtualFlow = VirtualFlow.createVertical(observableList, t-> {
            return new FindNode(t);
        });

        VBox vBox = new VBox(10);
        VirtualizedScrollPane virtualizedScrollPane = new VirtualizedScrollPane(virtualFlow);
        VBox.setVgrow(virtualizedScrollPane, Priority.ALWAYS);
        vBox.getChildren().addAll(virtualizedScrollPane, new Label("demo"));
        Scene scene = new Scene(vBox, 600, 400);
        primaryStage.setTitle("VirtualFlow Demo");
        primaryStage.setScene(scene);

        primaryStage.setOnCloseRequest(e->{
            ThreadPoolUtil.close();
        });
        primaryStage.show();

        ThreadPoolUtil.submit(()->{
            try {
                Path path = Paths.get("D:\\产业链金融\\测试\\gc\\catalina.out");
                FinderService finderService = new FinderService();
                int total = 10000;
                finderService.find(path.toFile(), "Result:", 500, fps->{
                    if (observableList.size() > total) return;
                    Platform.runLater(()->{
                        if (fps.size() + observableList.size() > total) {
                            observableList.addAll(fps.subList(0, total-observableList.size()));
                        } else {
                            observableList.addAll(fps);
                        }

                        System.out.println("size :" + observableList.size());
                    });
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private VBox buildCell(FindPosition findPosition) {
        VBox vBox = new VBox();
        TextFlow textFlow = new TextFlow();
        String str1 = findPosition.getArroundContent().substring(0, findPosition.getStart());
        String str2 = findPosition.getArroundContent().substring(findPosition.getStart(), findPosition.getEnd());
        String str3 = findPosition.getArroundContent().substring(findPosition.getEnd());
        Text text1 = new Text(str1);
        Text text2 = new Text(str2);
        text2.setFill(Color.BLUEVIOLET);
        Text text3 = new Text(str3);
        textFlow.getChildren().addAll(text1, text2, text3);
        vBox.getChildren().addAll(textFlow, new Separator());
        return vBox;
    }

    private VBox buildCell2(FindPosition findPosition) {
        VBox vBox = new VBox();
        CodeArea textArea = new CodeArea();
        textArea.insertText(0, findPosition.getArroundContent());
        Selection selection = new SelectionImpl<>(UUID.randomUUID().toString(), textArea, findPosition.getStart(), findPosition.getEnd());
        textArea.addSelection(selection);
        vBox.getChildren().addAll(textArea, new Separator());
        return vBox;
    }

    public static class FindNode implements Cell<FindPosition, TextFlow> {

        private FindPosition findPosition;
        private TextFlow textFlow = null;

        public FindNode(FindPosition findPosition) {
            textFlow = new TextFlow();
            this.findPosition = findPosition;
        }

        public TextFlow getNode() {
            textFlow.getChildren().add(new Text(findPosition.getArroundContent()));
            return textFlow;
        }

        public String toString() {
            return textFlow.toString();
        }
    }
}
